<template>
  <div
    ref="input"
    :class="{
      inp: true,
      focused,
    }"
    @click="onFocus"
  >
    {{ value }}
    <span v-show="focusLineVisible">|</span>
  </div>
</template>

<script>
let focusLineTimer = null;

export default {
  // 注册组件
  model: {
    prop: 'value',
    event: 'input',
  },
  props: {
    value: String,
  },
  data () {
    return {
      focused: false,
      focusLineVisible: false,
    };
  },
  watch: {
    focused (f) {
      if (f) {
        this.focusLineVisible = !this.focusLineVisible;
        focusLineTimer = setInterval(() => {
          this.focusLineVisible = !this.focusLineVisible;
        }, 500);
      } else {
        clearInterval(focusLineTimer);
        this.focusLineVisible = false;
      }
    },
  },
  methods: {
    onFocus () {
      this.focused = true;
    },
    onDocumentClick (e) {
      if (e.target !== this.$refs.input) {
        this.focused = false;
        this.$emit('blur', this.value);
      }
    },
    onKeyUp (e) {
      if (!this.focused) {
        return;
      }
      switch (e.key) {
        case 'Enter':
          this.$emit('change', this.value);
          break;
        case 'Backspace':
          this.$emit('input', this.value.substring(0, this.value.length - 1));
          break;
        default:
          this.$emit('input', this.value + e.key);
          break;
      }
    },
  },
  created () {
    document.addEventListener('click', this.onDocumentClick);
    document.addEventListener('keyup', this.onKeyUp);
  },
  beforeDestroy () {
    document.removeEventListener('click', this.onDocumentClick);
    document.removeEventListener('keyup', this.onKeyUp);
  },
}
</script>

<style scoped>
.inp.focused {
  outline: 1px solid red;
}
</style>